package com.cloudweb.oa.utils;

import cn.js.fan.util.ParamUtil;
import cn.js.fan.util.StrUtil;
import cn.js.fan.web.Global;
import com.cloudweb.oa.security.AuthUtil;
import com.cloudweb.oa.service.WorkflowService;
import com.cloudwebsoft.framework.util.LogUtil;
import com.redmoon.kit.util.FileUpload;
import com.redmoon.oa.Config;
import com.redmoon.oa.android.Privilege;
import com.redmoon.oa.base.IAttachment;
import com.redmoon.oa.flow.Attachment;
import com.redmoon.oa.security.SecurityUtil;
import com.redmoon.oa.sys.DebugUtil;
import com.redmoon.oa.util.Pdf2Html;
import org.springframework.security.access.method.P;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Component
public class AttachmentUtil {

    private final SysProperties sysProperties;

    public AttachmentUtil(SysProperties sysProperties) {
        this.sysProperties = sysProperties;
    }

    public void convertAttachment(int flowId, Attachment att, FileUpload fu, File f) {
        com.redmoon.oa.Config cfg = com.redmoon.oa.Config.getInstance();
        boolean canOfficeFilePreview = cfg.getBooleanProperty("canOfficeFilePreview");
        boolean canPdfFilePreview = cfg.getBooleanProperty("canPdfFilePreview");
        //ofd文件是否可以预览
        boolean canOfdFilePreview = cfg.getBooleanProperty("canOfdFilePreview");
        //docx文件能否转成ofd格式下载
        int isWordDownloadByOfd  = cfg.getInt("isWordDownloadByOfd");

        SysProperties sysProperties = SpringUtil.getBean(SysProperties.class);
        WorkflowService workflowService = SpringUtil.getBean(WorkflowService.class);
        long myActionId = StrUtil.toLong(fu.getFieldValue("myActionId"), -1);
        workflowService.addWatermark(myActionId, att);

        String previewfile = Global.getRealPath() + att.getVisualPath() + "/" + att.getDiskName();
        String ext = StrUtil.getFileExt(att.getDiskName());
        //上传 office文件是否可以预览，生成html文件
        if (canOfficeFilePreview) {
            if (FileUtil.isOfficeFile(att.getDiskName())) {
                PreviewUtil.createOfficeFilePreviewHTML(previewfile);
            }
        }

        //上传pdf文件是否可以预览，生成html文件
        if (canPdfFilePreview) {
            if ("pdf".equals(ext)) {
                Pdf2Html.createPreviewHTML(previewfile);
            }
        }

        //ofd文件可以预览
        if (canOfdFilePreview) {
            if ("ofd".equals(ext)) {
                workflowService.convertOfdToPfdToHtmlAsync(flowId, att, SpringUtil.getUserName(),"","");
            }
        }

        //isWordDownloadByOfd  docx文件能否转成ofd格式下载
        if (isWordDownloadByOfd == 1) {
            if ("docx".equals(ext)) {
                workflowService.convertToOfdAsync(flowId, att, SpringUtil.getUserName(),"","");
            }
        }

        // 转换为pdf
        if (FileUtil.isOfficeFile(att.getDiskName()) && cfg.getBooleanProperty("canConvertToPDF")) {
            workflowService.convertToPdfAsync(flowId, att, SpringUtil.getUserName(), null);
        }

        ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
        Runnable task = () -> {
            if (sysProperties.isObjStoreEnabled()) {
                // 删除本地文件
                if (!sysProperties.isObjStoreReserveLocalFile()) {
                    f.delete();
                }
            }
        };
        // 延迟120秒后执行
        executor.schedule(task, 120, TimeUnit.SECONDS);
        executor.shutdown();
    }

    /**
     * 用于流程及模块中附件栏中的文件生成预览
     * @param attachment
     * @return
     */
    public String getPreviewUrl(IAttachment attachment) {
        Config cfg = Config.getInstance();
        String url = "";
        boolean isValid = false;
        boolean isFlow = attachment instanceof Attachment;

        String ext = StrUtil.getFileExt(attachment.getDiskName());
        if (cfg.getBooleanProperty("canPdfFilePreview")) {
            if ("pdf".equals(ext)) {
                isValid = true;
            }
        }

        if (cfg.getBooleanProperty("canOfficeFilePreview")) {
            if ("doc".equals(ext) || "docx".equals(ext) || "xls".equals(ext) || "xlsx".equals(ext)) {
                isValid = true;
            }
        }

        if (cfg.getBooleanProperty("canOfdFilePreview")) {
            if (isFlow) {
                if ("ofd".equals(ext)) {
                    isValid = true;
                }
            }
        }
        boolean isImg = StrUtil.isImage(ext);
        SysUtil sysUtil = SpringUtil.getBean(SysUtil.class);

        if (isValid) {
            int officeFilePreViewCreateMode = cfg.getInt("officeFilePreViewCreateMode");
            LogUtil.getLog(getClass()).info("officeFilePreViewCreateMode=" + officeFilePreViewCreateMode);
            if (FileUtil.isOfficeFile(attachment.getDiskName())) {
                // wps 在线预览
                if (officeFilePreViewCreateMode == 2) {
                    return "#" + attachment.getId();
                } else if (officeFilePreViewCreateMode == 5) {
                    // Onlyoffice 预览
                    return "&" + attachment.getId();
                }
            }

            int pdfFilePreViewCreateMode = cfg.getInt("pdfFilePreViewCreateMode");
            if (pdfFilePreViewCreateMode == 1 && FileUtil.isPdfFile(attachment.getDiskName())) {
                return "@" + sysUtil.getRootPath() + "/public/preview?id=" + attachment.getId() + "&isFlow=" + isFlow + "&visitKey=" + SecurityUtil.makeVisitKey(String.valueOf(attachment.getId()));
            }

            // 微软在线预览
            if (officeFilePreViewCreateMode == 3) {
                if (FileUtil.isOfficeFile(attachment.getDiskName())) {
                    return "@https://view.officeapps.live.com/op/view.aspx?src=" + StrUtil.UrlEncode(sysUtil.getRootPath() + "/" + attachment.getVisualPath() + "/" + attachment.getDiskName());
                }
            }

            if (!Global.isCluster() && !sysProperties.isObjStoreEnabled()) {
                String s = Global.getRealPath() + attachment.getVisualPath() + "/" + attachment.getDiskName();
                int p = s.lastIndexOf(".");
                if (p != -1) {
                    String htmlfile = s.substring(0, p) + ".html";
                    java.io.File fileExist = new java.io.File(htmlfile);
                    if (fileExist.exists()) {
                        url = sysUtil.getRootPath() + "/" + attachment.getVisualPath() + "/" + attachment.getDiskName().substring(0, attachment.getDiskName().lastIndexOf(".")) + ".html";
                    }
                } else {
                    DebugUtil.e(getClass(), "getPreviewUrl", "附件 " + attachment.getId() + " 文件名 " + attachment.getDiskName() + " 非法");
                }
            } else {
                url = sysUtil.getRootPath() + "/" + attachment.getVisualPath() + "/" + attachment.getDiskName().substring(0, attachment.getDiskName().lastIndexOf(".")) + ".html";
            }
        } else if (isImg) {
            url = sysUtil.getRootPath() + "/showImg?path=" + attachment.getVisualPath() + "/" + attachment.getDiskName();
        } else if (FileUtil.isVideo(attachment.getDiskName())) {
            url = sysUtil.getRootPath() + "/" + attachment.getVisualPath() + "/" + attachment.getDiskName();
        }
        return url;
    }

    /**
     * 用于文件及文件组控件生成预览链接
     * @param att
     * @param isFlow
     * @return
     */
    public String getCtlPreviewUrl(IAttachment att, boolean isFlow) {
        SysUtil sysUtil = SpringUtil.getBean(SysUtil.class);
        long t = System.currentTimeMillis();
        String previewUrl = "";

        boolean isPreview = false;
        Config cfg = Config.getInstance();
        // 判断是否为wps、word文件
        if (FileUtil.isPdfFile(att.getDiskName())) {
            if (cfg.getBooleanProperty("canPdfFilePreview")) {
                isPreview = true;
            }
        } else if (FileUtil.isOfficeFile(att.getDiskName())) {
            if (cfg.getBooleanProperty("canOfficeFilePreview")) {
                isPreview = true;
            }
        }

        if (StrUtil.isImage(StrUtil.getFileExt(att.getDiskName()))) {
            String visitKeyImg = SecurityUtil.makeVisitKey(att.getVisualPath() + "/" + att.getDiskName());
            return "<a href='javascript:;' onclick=\"window.open('" + sysUtil.getRootPath() +"/showImg.do?visitKey=" + visitKeyImg + "&path="+ att.getVisualPath() + "/" + att.getDiskName() + "')\">查看</a>";
        } else {
            if (isPreview) {
                int pdfFilePreViewCreateMode = cfg.getInt("pdfFilePreViewCreateMode");
                // pdf文件采用iframe预览方式
                if (pdfFilePreViewCreateMode == 1 && FileUtil.isPdfFile(att.getDiskName())) {
                    previewUrl = "<a href='javascript:;' onclick=\"window.preview('" + sysUtil.getRootPath() + "/public/preview?id=" + att.getId() + "&isFlow=" + isFlow + "&visitKey=" + SecurityUtil.makeVisitKey(String.valueOf(att.getId()), true) + "')\">预览</a>";
                } else {
                    // 微软在线预览
                    int officeFilePreViewCreateMode = cfg.getInt("officeFilePreViewCreateMode");
                    if (officeFilePreViewCreateMode == 3 && FileUtil.isOfficeFile(att.getDiskName())) {
                        previewUrl = "<a href='javascript:;' onclick=\"window.preview('" + "https://view.officeapps.live.com/op/view.aspx?src=" + StrUtil.UrlEncode(sysUtil.getRootPath() + "/" + att.getVisualPath() + "/" + att.getDiskName()) + "')\">预览</a>";
                    } else {
                        if (officeFilePreViewCreateMode == 5) {
                            int flowId = -1;
                            if (att instanceof Attachment) {
                                flowId = ((Attachment) att).getFlowId();
                            }
                            Privilege privilege = new Privilege();
                            AuthUtil authUtil = SpringUtil.getBean(AuthUtil.class);
                            String skey = privilege.getSkey(authUtil.getUserName());
                            previewUrl = "#/onlyoffice?type=" + (isFlow?"flow":"module") + "&id=" + att.getId() + "&name=" + StrUtil.UrlEncode(att.getName()) + "&mode=r&flowId=" + flowId + "&actionId=-1&ext=" + StrUtil.getFileExt(att.getDiskName()) + "&onlyofficeServerUrl=" + sysProperties.getOnlyOfficeServerUrl() + "&token=" + skey;
                        } else {
                            // 网络环境下，Tomcat方式部署时有时会比较耗时，故在集群时不判断文件是否存在
                            boolean isFileExist = true;
                            if (!Global.isCluster()) {
                                String s = Global.getRealPath() + att.getVisualPath() + "/" + att.getDiskName();
                                String htmlfile = s.substring(0, s.lastIndexOf(".")) + ".html";
                                java.io.File fileExist = new java.io.File(htmlfile);
                                isFileExist = fileExist.exists();
                                if (Global.getInstance().isDebug()) {
                                    LogUtil.getLog(getClass()).info("after exists " + htmlfile + " take " + (System.currentTimeMillis() - t) + " ms");
                                }
                            }
                            if (isFileExist) {
                                previewUrl = "<a href='javascript:;' onclick=\"window.open('" + sysUtil.getRootPath() + "/" + att.getVisualPath() + "/" + att.getDiskName().substring(0, att.getDiskName().lastIndexOf(".")) + ".html" + "')\">预览</a>";
                            }
                        }
                    }
                }
            }
        }
        return previewUrl;
    }

    /**
     * 用于文件及文件组宏控件在手机端及PC端列表中生成预览链接
     * @param att
     * @param isFlow
     * @return
     */
    public String getCtlPreviewUrlForMetadata(IAttachment att, boolean isFlow) {
        HttpServletRequest request = SpringUtil.getRequest();
        if (request != null && ParamUtil.isMobile(request)) {
            if (FileUtil.isVideo(att.getDiskName())) {
                return att.getVisualPath() + "/" + att.getDiskName();
            }
        }

        String previewUrl = "";
        if (StrUtil.isImage(StrUtil.getFileExt(att.getDiskName()))) {
            previewUrl = att.getVisualPath() + "/" + att.getDiskName();
        } else {
            if (StrUtil.isImage(StrUtil.getFileExt(att.getDiskName()))) {
                previewUrl = att.getVisualPath() + "/" + att.getDiskName();
            } else {
                Config cfg = Config.getInstance();
                boolean isPreview = false;
                // 判断是否为wps、word文件
                if (FileUtil.isPdfFile(att.getDiskName())) {
                    if (cfg.getBooleanProperty("canPdfFilePreview")) {
                        isPreview = true;
                    }
                } else if (FileUtil.isOfficeFile(att.getDiskName())) {
                    if (cfg.getBooleanProperty("canOfficeFilePreview")) {
                        isPreview = true;
                    }
                }

                if (isPreview) {
                    SysUtil sysUtil = SpringUtil.getBean(SysUtil.class);
                    int pdfFilePreViewCreateMode = cfg.getInt("pdfFilePreViewCreateMode");
                    // iframe方式预览pdf
                    if (pdfFilePreViewCreateMode == 1 && FileUtil.isPdfFile(att.getDiskName())) {
                        previewUrl = "/public/preview?id=" + att.getId() + "&isFlow=" + isFlow + "&visitKey=" + SecurityUtil.makeVisitKey(String.valueOf(att.getId()));
                    } else {
                        // 微软在线预览
                        int officeFilePreViewCreateMode = cfg.getInt("officeFilePreViewCreateMode");
                        if (officeFilePreViewCreateMode == 3 && FileUtil.isOfficeFile(att.getDiskName())) {
                            previewUrl = "https://view.officeapps.live.com/op/embed.aspx?src=" + StrUtil.UrlEncode(sysUtil.getRootPath() + "/" + att.getVisualPath() + "/" + att.getDiskName());
                        } else {
                            if (officeFilePreViewCreateMode == 5) {
                                int flowId = -1;
                                if (att instanceof Attachment) {
                                    flowId = ((Attachment) att).getFlowId();
                                }
                                Privilege privilege = new Privilege();
                                AuthUtil authUtil = SpringUtil.getBean(AuthUtil.class);
                                String skey = privilege.getSkey(authUtil.getUserName());
                                previewUrl = "#/onlyoffice?type=" + (isFlow?"flow":"module") + "&id=" + att.getId() + "&name=" + StrUtil.UrlEncode(att.getName()) + "&mode=r&flowId=" + flowId + "&actionId=-1&ext=" + StrUtil.getFileExt(att.getDiskName()) + "&onlyofficeServerUrl=" + sysProperties.getOnlyOfficeServerUrl() + "&token=" + skey;
                            } else {
                                // 网络环境下，Tomcat方式部署时有时会比较耗时，故在集群时不判断文件是否存在
                                boolean isFileExist = true;
                                if (!Global.isCluster()) {
                                    String s = Global.getRealPath() + att.getVisualPath() + "/" + att.getDiskName();
                                    String htmlfile = s.substring(0, s.lastIndexOf(".")) + ".html";
                                    java.io.File fileExist = new java.io.File(htmlfile);
                                    isFileExist = fileExist.exists();
                                }
                                if (isFileExist) {
                                    previewUrl = att.getVisualPath() + "/" + att.getDiskName().substring(0, att.getDiskName().lastIndexOf(".")) + ".html";
                                }
                            }
                        }
                    }
                }
            }
        }
        return previewUrl;
    }

    /**
     * 仅用于在嵌套表格的列表中生成文件宏控件的预览链接
     * @param iAtt
     * @param isFlow
     * @return
     */
    public String getCtlPreviewUrlForList(IAttachment iAtt, boolean isFlow) {
        Config cfg = Config.getInstance();
        boolean isPreview = false;
        String previewUrl = "";
        boolean isImage = false;
        if (StrUtil.isImage(StrUtil.getFileExt(iAtt.getDiskName()))) {
            isImage = true;
        } else {
            // 判断是否为wps、word文件
            if (FileUtil.isPdfFile(iAtt.getDiskName())) {
                if (cfg.getBooleanProperty("canPdfFilePreview")) {
                    isPreview = true;
                }
            } else if (FileUtil.isOfficeFile(iAtt.getDiskName())) {
                if (cfg.getBooleanProperty("canOfficeFilePreview")) {
                    isPreview = true;
                }
            }
        }

        SysUtil sysUtil = SpringUtil.getBean(SysUtil.class);
        if (isPreview) {
            int pdfFilePreViewCreateMode = cfg.getInt("pdfFilePreViewCreateMode");
            if (pdfFilePreViewCreateMode == 1 && FileUtil.isPdfFile(iAtt.getDiskName())) {
                previewUrl = "&nbsp;&nbsp;<a href='javascript:;' onclick=\"window.preview('" + sysUtil.getRootPath() + "/public/preview?id=" + iAtt.getId() + "&isFlow=" + isFlow + "&visitKey=" + SecurityUtil.makeVisitKey(String.valueOf(iAtt.getId()), true) + "')\">预览</a>";
            } else {
                // 微软在线预览
                int officeFilePreViewCreateMode = cfg.getInt("officeFilePreViewCreateMode");
                if (officeFilePreViewCreateMode == 3 && FileUtil.isOfficeFile(iAtt.getDiskName())) {
                    previewUrl = "&nbsp;&nbsp;<a href='javascript:;' onclick=\"window.preview('" + "https://view.officeapps.live.com/op/view.aspx?src=" + StrUtil.UrlEncode(sysUtil.getRootPath() + "/" + iAtt.getVisualPath() + "/" + iAtt.getDiskName()) + "')\">预览</a>";
                } else {
                    // 网络环境下，Tomcat方式部署时有时会比较耗时，故在集群时不判断文件是否存在
                    boolean isFileExist = true;
                    if (!Global.isCluster()) {
                        String s = Global.getRealPath() + iAtt.getVisualPath() + "/" + iAtt.getDiskName();
                        String htmlfile = s.substring(0, s.lastIndexOf(".")) + ".html";
                        java.io.File fileExist = new java.io.File(htmlfile);
                        isFileExist = fileExist.exists();
                    }
                    if (isFileExist) {
                        previewUrl = sysUtil.getRootPath() + "/" + iAtt.getVisualPath() + "/" + iAtt.getDiskName().substring(0, iAtt.getDiskName().lastIndexOf(".")) + ".html";
                    }
                }
            }
        }

        if (isImage) {
            String visitKeyImg = SecurityUtil.makeVisitKey(iAtt.getVisualPath() + "/" + iAtt.getDiskName());
            previewUrl = "&nbsp;&nbsp;<a href='javascript:;' onclick=\"window.open('" + sysUtil.getRootPath() +"/showImg.do?visitKey=" + visitKeyImg + "&path="+ iAtt.getVisualPath() + "/" + iAtt.getDiskName() + "')\">查看</a>";
        } else {
            if (!"".equals(previewUrl)) {
                previewUrl = "&nbsp;&nbsp;<a href='javascript:;' onclick=\"window.open('" + sysUtil.getRootPath() + "/" + iAtt.getVisualPath() + "/" + iAtt.getDiskName().substring(0, iAtt.getDiskName().lastIndexOf(".")) + ".html')\">预览</a>";
            }
        }
        return previewUrl;
    }
}
